<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/react.development.js"></script>
    <script src="../js/react-dom.development.js"></script>
    <script src="../js/babel.min.js"></script>
</head>
<body>
    <div id="test">

    </div>
    <script type="text/babel">

        //定义一个Weather组件
        class Weather extends React.Component{
            // 构造器 --- 调用几次？ --- 1次
            constructor(props){
                super(props);
                // 初始化状态---state:状态
                this.state={ isHot:true}

                // 下面代码执行完之后，Weather实例对象中的this则是实例对象自身
                // 第二个this是对象实例，通过this.changeWeather能找到原型链上的changeWeather方法，并调用bind(this)修改其指向到实例对象自身，最后把这个this.changeWeather.bind(this)(其实就是一个方法)复制给this.changeWeather,也就是实例对象自身也会有changeWeather方法，且指向实例对象自身
                // 给实例自身追加一个同名的 changeWeather 方法，这个方法是根据原型上的changeWeather用bind生成的，他的this没问题
                this.changeWeather = this.changeWeather.bind(this)
            }   
            // 必须要写的render --- 调用几次？ --- 1+n次，n是改变状态的次数 
            render(){
                // console.log(this);   //实例对象
                // const {isHot} = this.state;  //解构赋值

                // 没有其他代码时，this.changeWeather 在react中执行的机制是：
                // ① x = this.changeWeather ;  ② x() 
                // 如果类中的方法是以 实例.方法 调用的，如w.changeWeather()，那么方法中的this就是实例对象
                // 但是 this.changeWeather 不属于 实例.方法调用，它是将this.changeWeather缓存给x变量，等到点击事件发生时，调用x(),这个属于changeWeather的直接调用，类中的方法直接调用时，会默认开启严格模式，this指的是undefined
                return <h1 onClick={this.changeWeather}>今天天气很{this.state.isHot ? '炎热' : '凉爽'}</h1>
            }
            // 程序员根据业务逻辑自己定义的事件回调 --- 调用几次？ --- n次，n是点击的次数
            /*  
                changeWeather函数是放在哪里的？ --- Weather 的原型对象上，供实例使用
                changeWeather函数中的this是谁？ --- 如果show 是通过Weather实例调用的，那么this就是Weather的实例对象
                --- 但是此时的show函数，是作为点击事件的回调函数们根本就不是通过weather的实例调用的，而且类中的方法自动开启了严格模式，故方法中的this是undefined
            */ 
            changeWeather(){
                // 获取isHot的值
                console.log('@',this);

                // 严重注意：state不可以直接修改，要用setState去修改，下面这行是直接修改
                // this.state.isHot=true

                const isHot = this.state.isHot
                this.setState({isHot:!isHot})// 取反赋值回去
            }
        }
        // 渲染组件到页面
        ReactDOM.render(<Weather/>,document.getElementById('test'))

    </script>
</body>
</html>